package jinyilw.common;

import jinyilw.common.app.AppConfig;
import jinyilw.common.file.FileTools;
import jinyilw.common.log.LogTools;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Properties;
import java.util.concurrent.ConcurrentHashMap;

public class SettingTools
{
	private static ConcurrentHashMap<String, SettingTools> toolsMap;
	private static volatile SettingTools defaultTools;
	private File settingsFile;
	private Properties properties;
	private String description;

	private SettingTools(File file)
	{
		this(file, null);
	}

	private SettingTools(File file, String description)
	{
		if (file == null)
			return;
		settingsFile = file;
		this.description = description;
		properties = getProperties(file);
	}

	public static SettingTools getTools(File file)
	{
		if (file == null)
			return null;
		if (toolsMap == null)
		{
			toolsMap = new ConcurrentHashMap<>();
			AppConfig.addAppExitedOperator(o -> {
				for (SettingTools tools : toolsMap.values())
					tools.saveSetting();
			});
		}
		String key = file.getAbsolutePath();
		if (toolsMap.containsKey(key))
			return toolsMap.get(key);
		SettingTools tools = new SettingTools(file);
		toolsMap.put(key, tools);
		return tools;
	}

	public static Properties getProperties(String path)
	{
		return getProperties(FileTools.getUserFile(path));
	}

	public static Properties getProperties(File file)
	{
		if (file == null)
			return null;
		FileInputStream b = null;
		Properties properties = new Properties();
		try
		{
			b = new FileInputStream(file);
		} catch (Exception e)
		{
			LogTools.debug("打开" + file.getName() + "文件出错！", e);
		}
		if (b != null)
		{
			try
			{
				properties.load(b);
				b.close();
			} catch (IOException e)
			{
				e.printStackTrace();
			}
		}
		return properties;
	}

	public static void saveProperties(Properties settings, File file,
			String description)
	{
		if (settings == null || file == null)
			return;
		FileOutputStream output = null;
		try
		{
			output = new FileOutputStream(file);
		} catch (Exception e)
		{
			e.printStackTrace();
		}
		if (output != null)
		{
			try
			{
				settings.store(output, description);
				output.close();
			} catch (IOException e)
			{
				e.printStackTrace();
			}
		}
	}

	public static SettingTools getDefaultTools()
	{
		if (defaultTools == null)
			synchronized (SettingTools.class)
			{
				if (defaultTools == null)
					defaultTools = getTools(AppConfig.getAppSettingsFile());
			}
		return defaultTools;
	}

	public static void putDefaultSettingData(String key, Object data)
	{
		getDefaultTools().putData(key, data);
	}

	public static Object getDefaultSettingData(String key, Object defaultData)
	{
		return getDefaultTools().getData(key, defaultData);
	}

	public static String getDefaultString(String name, String defaultValue)
	{
		return getDefaultTools().getString(name, defaultValue);
	}

	public static int getDefaultInt(String name, int defaultValue)
	{
		return getDefaultTools().getInt(name, defaultValue);
	}

	public static double getDefaultDouble(String name, double defaultValue)
	{
		return getDefaultTools().getDouble(name, defaultValue);
	}

	public static float getDefaultFloat(String name, float defaultValue)
	{
		return getDefaultTools().getFloat(name, defaultValue);
	}

	public static boolean getDefaultBool(String name, boolean defaultValue)
	{
		return getDefaultTools().getBool(name, defaultValue);
	}

	private static String trimValue(String value)
	{
		if (value == null)
			return null;
		if (value.isEmpty())
			return value;
		int lastpos = value.indexOf('#');
		if (lastpos == -1)
			lastpos = value.length() - 1;
		else
			lastpos--;
		while ((lastpos >= 0) && ((value.charAt(lastpos) == ' ')
				|| (value.charAt(lastpos) == '\t')))
			lastpos--;
		return value.substring(0, lastpos + 1);
	}

	public Properties getProperties()
	{
		return properties;
	}

	public void putData(String key, Object data)
	{
		if (key == null || data == null)
			return;
		properties.setProperty(key, data.toString());
	}

	public Object getData(String key, Object defaultData)
	{
		Object object = null;
		if (defaultData instanceof Integer)
			object = getInt(key, (Integer) defaultData);
		else if (defaultData instanceof Double)
			object = getDouble(key, (Double) defaultData);
		else if (defaultData instanceof Boolean)
			object = getBool(key, (Boolean) defaultData);
		else if (defaultData instanceof String)
			object = getString(key, (String) defaultData);
		else if (defaultData instanceof Float)
			object = getFloat(key, (Float) defaultData);
		// else if (defautData instanceof Long)
		// object = getLong(key, (Long) defautData);
		return object;
	}

	public synchronized void saveSetting()
	{
		LogTools.info("保存设置文件：" + settingsFile.getName());
		saveProperties(properties, settingsFile, description);
	}

	public void setSettingFile(File file)
	{
		if (file == null)
			return;
		settingsFile = file;
		properties = getProperties(file);
	}

	public String getString(String name, String defaultValue)
	{
		if (properties == null)
			return defaultValue;
		String propertyValue = properties.getProperty(name);
		LogTools.info("获取设置：" + name + "=" + propertyValue);
		if (propertyValue != null)
			return propertyValue.trim();
		return defaultValue;
	}

	public int getInt(String name, int defaultValue)
	{
		if (properties == null)
			return defaultValue;
		String propertyValue = trimValue(properties.getProperty(name));
		if (propertyValue == null)
			return defaultValue;
		int val;
		try
		{
			val = Integer.parseInt(propertyValue);
		} catch (NumberFormatException err)
		{
			return defaultValue;
		}
		return val;
	}

	public double getDouble(String name, double defaultValue)
	{
		if (properties == null)
			return defaultValue;
		String propertyValue = trimValue(properties.getProperty(name));
		if (propertyValue == null)
			return defaultValue;
		double val;
		try
		{
			val = Double.parseDouble(propertyValue);
		} catch (NumberFormatException err)
		{
			return defaultValue;
		}
		return val;
	}

	public float getFloat(String name, float defaultValue)
	{
		if (properties == null)
			return defaultValue;
		String propertyValue = trimValue(properties.getProperty(name));
		if (propertyValue == null)
			return defaultValue;
		float val;
		try
		{
			val = Float.parseFloat(propertyValue);
		} catch (NumberFormatException err)
		{
			return defaultValue;
		}
		return val;
	}

	public boolean getBool(String name, boolean defaultValue)
	{
		if (properties == null)
			return defaultValue;
		String propertyValue = trimValue(properties.getProperty(name));
		if (propertyValue == null)
			return defaultValue;
		return "true".equals(propertyValue);
	}

	//	public Color getColor(String name, Color... defaultColor)
	//	{
	//		if (properties == null)
	//			return defaultColor.length > 0
	//					? defaultColor[0]
	//					: new Color(0, 0, 0);
	//		String propertyValue = trimValue(properties.getProperty(name));
	//		if (propertyValue == null)
	//		{
	//			return defaultColor.length > 0
	//					? defaultColor[0]
	//					: new Color(0, 0, 0);
	//		}
	//		if (propertyValue.startsWith("#"))
	//			propertyValue = propertyValue.substring(1);
	//		return new Color(Integer.parseInt(propertyValue));
	//	}

	//	public Color getColor(String name, Color... defaultColor)
	//	{
	//		if (properties == null)
	//			return defaultColor.length > 0
	//					? defaultColor[0]
	//					: new Color(0, 0, 0);
	//		;
	//		String propertyValue = trimValue(properties.getProperty(name));
	//		if (propertyValue == null)
	//		{
	//			return defaultColor.length > 0
	//					? defaultColor[0]
	//					: new Color(0, 0, 0);
	//		}
	//		String[] colorString = propertyValue.split(",");
	//		if (colorString.length == 4)
	//		{
	//			try
	//			{
	//				return new Color(
	//						Integer.decode(colorString[0].trim()).intValue(),
	//						Integer.decode(colorString[1].trim()).intValue(),
	//						Integer.decode(colorString[2].trim()).intValue(),
	//						Integer.decode(colorString[3].trim()).intValue());
	//			} catch (NumberFormatException e)
	//			{
	//			}
	//		}
	//		if (colorString.length == 3)
	//		{
	//			try
	//			{
	//				return new Color(
	//						Integer.decode(colorString[0].trim()).intValue(),
	//						Integer.decode(colorString[1].trim()).intValue(),
	//						Integer.decode(colorString[2].trim()).intValue());
	//			} catch (NumberFormatException e)
	//			{
	//			}
	//		}
	//		return new Color(0, 0, 0);
	//	}
}
